
/*
 * ApexDC speedmod (c) SMT 2007
 */

#include "stdafx.h"
#include "../client/DCPlusPlus.h"
#include "../client/Util.h"
#include "../client/StringTokenizer.h"
#include "../client/ShareManager.h"
#include "../client/ClientManager.h"
#include "../client/TimerManager.h"
#include "../client/FavoriteManager.h"
#include "../client/ResourceManager.h"
#include "../client/QueueManager.h"
#include "../client/UploadManager.h"
#include "../client/HashManager.h"
#include "../client/LogManager.h"
#include "resource.h"
#include "../client/UserInfoBase.h"
#include "PrivateFrame.h"
#include "LineDlg.h"

void UserInfoBase::matchQueue(const string& hubHint)
{
	if (getUser())
	{
		// [+] SSA Do not ask filelist from zero-share users?
		bool askFileList = true;
		if (!BOOLSETTING(FILE_LIST_FROM_ZERO_SHARE_USERS))
			askFileList = getUser()->getBytesShared() > 0;
		if (askFileList)
		{
			try
			{
				QueueManager::getInstance()->addList(HintedUser(getUser(), hubHint), QueueItem::FLAG_MATCH_QUEUE);
			}
			catch (const Exception& e)
			{
				LogManager::getInstance()->message(e.getError());
			}
		}
	}
}
void UserInfoBase::getUserResponses(const string& hubHint)
{
	if (getUser())
	{
		try
		{
			QueueManager::getInstance()->addCheckUserIP(HintedUser(getUser(), hubHint)); // [+] SSA
		}
		catch (const Exception& e)
		{
			LogManager::getInstance()->message(e.getError());
		}
	}
}

void UserInfoBase::doReport(const string& hubHint)
{
	if (getUser())
	{
		ClientManager::getInstance()->reportUser(HintedUser(getUser(), hubHint));
	}
}

void UserInfoBase::getList(const string& hubHint)
{
	if (getUser())
	{
		// [+] SSA Do not ask filelist from zero-share users?
		bool askFileList = true;
		if (!BOOLSETTING(FILE_LIST_FROM_ZERO_SHARE_USERS))
			askFileList = getUser()->getBytesShared() > 0;
		if (askFileList)
		{
			try
			{
				QueueManager::getInstance()->addList(HintedUser(getUser(), hubHint), QueueItem::FLAG_CLIENT_VIEW);
			}
			catch (const Exception& e)
			{
				LogManager::getInstance()->message(e.getError());
			}
		}
	}
}
void UserInfoBase::browseList(const string& hubHint)
{
	if (getUser())
	{
		if (getUser()->getCID().isZero())
			return;
			
		// [+] SSA Do not ask filelist from zero-share users?
		bool askFileList = true;
		if (!BOOLSETTING(FILE_LIST_FROM_ZERO_SHARE_USERS))
			askFileList = getUser()->getBytesShared() > 0;
		if (askFileList)
		{
		
			try
			{
				//QueueManager::getInstance()->addPfs(user, "");
				QueueManager::getInstance()->addList(HintedUser(getUser(), hubHint), QueueItem::FLAG_CLIENT_VIEW | QueueItem::FLAG_PARTIAL_LIST);
			}
			catch (const Exception& e)
			{
				LogManager::getInstance()->message(e.getError());
			}
		}
	}
}
// [-] IRainman old, dead code
//void UserInfoBase::checkList(const string& hubHint)
//{
//  if (getUser())
//  {
//      try
//      {
//          QueueManager::getInstance()->addList(HintedUser(getUser(), hubHint), QueueItem::FLAG_CHECK_FILE_LIST);
//      }
//      catch (const Exception& e)
//      {
//          LogManager::getInstance()->message(e.getError());
//      }
//  }
//}
void UserInfoBase::addFav()
{
	if (getUser())
	{
		FavoriteManager::getInstance()->addFavoriteUser(getUser());
	}
}
// [+] SSA add BAN for User
void UserInfoBase::addBan()
{
	if (getUser())
	{
		FavoriteManager::getInstance()->addFavoriteUserToBan(getUser());
	}
}
// [+] SSA add Ignore for User
void UserInfoBase::addIgnore()
{
	if (getUser())
	{
		FavoriteManager::getInstance()->addFavoriteUserToIgnore(getUser());
	}
}


void UserInfoBase::delFav()
{
	if (getUser())
	{
		FavoriteManager::getInstance()->removeFavoriteUser(getUser());
	}
}

void UserInfoBase::pm(const string& hubHint)
{
	if (getUser())
	{
		// TODO provide client
		PrivateFrame::openWindow(HintedUser(getUser(), hubHint), Util::emptyStringT, NULL);
	}
}
// !SMT!-UI
void UserInfoBase::addSummary()
{
	if (!getUser())
		return;

	HCURSOR hcurPrev = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
	//{
	/*  ClientManager::LockInstance l_lockInstance;
	if (OnlineUser *ou = ClientManager::getInstance()->getOnlineUser(user)) {
	        l_share = ou->getIdentity().getBytesShared();
	        const int l_slots = ou->getIdentity().getSlots();
	        const int l_limit = ou->getIdentity().getLimit();
	        userInfo = userInfo + _T("Slots=") + Util::toStringW(l_slots) + _T(" Share=") + Util::formatBytesW(l_share);
	        if (l_limit)
	            userInfo = userInfo + _T(" Limit=") + Util::toStringW(l_limit) + CWSTRING(KBPS);
	}*/
	WinUtil::userSummaryMenu.InsertSeparatorLast(Text::toT(getUser()->getFirstNick()));

	{
		string ip;
		uint64_t l_share = 0;
		int l_slots = 0;
		int l_limit = 0;
		if (ClientManager::getInstance()->getUserParams(getUser(), &l_share, &l_slots, &l_limit, &ip))
		{
			tstring userInfo = _T("Slots=") + Util::toStringW(l_slots) + _T(" Share=") + Util::formatBytesW(l_share); // TODO translate
			
			if (l_limit)
				userInfo += _T(" Limit=") + Util::toStringW(l_limit) + CWSTRING(KBPS); // TODO translate

			WinUtil::userSummaryMenu.AppendMenu(MF_STRING | MF_DISABLED, IDC_NONE, userInfo.c_str());

			time_t slot = UploadManager::getInstance()->getReservedSlotTime(getUser());
			if (slot)
			{
				tstring note = TSTRING(EXTRA_SLOT_TIMEOUT) + _T(": ") + Util::formatSeconds((slot - GET_TICK()) / 1000);
				WinUtil::userSummaryMenu.AppendMenu(MF_STRING | MF_DISABLED, IDC_NONE, note.c_str());
			}

			if (!ip.empty())
			{
				string dns;
#ifdef PPA_INCLUDE_DNS
				dns = Socket::nslookup(ip);
				if (ip == dns)
					dns = "no DNS"; // TODO translate
				if (!dns.empty())
					dns = " / " + dns;
#endif
				WinUtil::userSummaryMenu.AppendMenu(MF_STRING | MF_DISABLED, IDC_NONE, (Text::toT("IP: " + ip + dns)).c_str());
				HubFrame::addDupeUsersToSummaryMenu(l_share, ip);
			}
		}
	}

	//WinUtil::userSummaryMenu.AppendMenu(MF_SEPARATOR);

	bool caption = false;
	UploadQueueItem::SlotQueue users = UploadManager::getInstance()->getUploadQueue();
	for (UploadQueueItem::SlotQueue::const_iterator uit = users.begin(); uit != users.end(); ++uit)
	{
		if (uit->first.user.user != getUser()) continue;
		for (UploadQueueItem::Iter i = uit->second.begin(); i != uit->second.end(); ++i)
		{
			if (!caption)
			{
				WinUtil::userSummaryMenu.InsertSeparatorLast(TSTRING(USER_WAIT_MENU));
				caption = true;
			}
			(*i)->update();
			
			tstring note =
				tstring(_T("[")) +
				Text::toT(Util::toString((double)(*i)->getPos() * 100.0 / (double)(*i)->getSize())) +
				tstring(_T("% ")) +
				Util::formatSeconds(GET_TIME() - (*i)->getTime()) +
				tstring(_T("]\x09")) +
				(*i)->getText(UploadQueueItem::COLUMN_FILE);
			WinUtil::userSummaryMenu.AppendMenu(MF_STRING | MF_DISABLED, IDC_NONE, note.c_str());
		}
	}
	caption = false;
	{
		QueueManager::LockInstance l_fileQueue;
		const QueueItem::StringMap& downloads = l_fileQueue.get();
		for (QueueItem::StringMap::const_iterator j = downloads.begin(); j != downloads.end(); ++j)
		{
			QueueItem* aQI = j->second;
			bool src = aQI->isSource(getUser()), badsrc = false;
			if (!src) badsrc = aQI->isBadSource(getUser());
			if (src || badsrc)
			{
				if (!caption)
				{
					WinUtil::userSummaryMenu.InsertSeparatorLast(TSTRING(NEED_USER_FILES_MENU));
					caption = true;
				}
				tstring note = Text::toT(aQI->getTarget());
				if (aQI->getSize() > 0)
					note = note + tstring(_T("\x09(")) + Text::toT(Util::toString((double)aQI->getDownloadedBytes() * 100.0 / (double)aQI->getSize())) + tstring(_T("%)"));
				UINT flags = MF_STRING | MF_DISABLED;
				if (badsrc) flags |= MF_GRAYED;
				WinUtil::userSummaryMenu.AppendMenu(flags, IDC_NONE, note.c_str());
			}
		}
	}

	::SetCursor(hcurPrev);
}
// !SMT!-S
const tstring UserInfoBase::getBroadcastPrivateMessage()
{
	static tstring deftext = _T("");
	LineDlg dlg;
	dlg.description = TSTRING(PRIVATE_MESSAGE);
	dlg.title = TSTRING(SEND_TO_ALL_USERS);
	dlg.line = deftext;
	if (dlg.DoModal() == IDOK)
	{
		deftext = dlg.line;
		return deftext;
	}
	else // cancel
		return _T("\x01");
}
uint64_t UserInfoBase::inputSlotTime()
{
	static tstring deftext = _T("00:30");
	LineDlg dlg;
	dlg.description = TSTRING(EXTRA_SLOT_TIME_FORMAT);
	dlg.title = TSTRING(EXTRA_SLOT_TIMEOUT);
	dlg.line = deftext;
	if (dlg.DoModal() == IDOK)
	{
		deftext = dlg.line;
		int n = 0;
		for (size_t i = 0; i < deftext.length(); i++)
			if (deftext[i] == ':') n++;
		int d, h, m;
		switch (n)
		{
			case 1:
				swscanf(deftext.c_str(), L"%d:%d", &h, &m);
				return (h * 3600 + m * 60);
			case 2:
				swscanf(deftext.c_str(), L"%d:%d:%d", &d, &h, &m);
				return (d * 3600 * 24 + h * 3600 + m * 60);
			default:
				::MessageBox(GetForegroundWindow(), CTSTRING(INVALID_TIME_FORMAT), CTSTRING(ERRORS), MB_OK | MB_ICONERROR);
				return 0;
		}
	} // else // cancel
	return 0;
}
void UserInfoBase::grant(const string& hubHint)
{
	if (getUser())
	{
		UploadManager::getInstance()->reserveSlot(HintedUser(getUser(), hubHint), 600);
	}
}
void UserInfoBase::removeAll()
{
	if (getUser())
	{
		QueueManager::getInstance()->removeSource(getUser(), QueueItem::Source::FLAG_REMOVED);
	}
}
/*
void UserInfoBase::grantSlotHour()
{
    if(getUser())
    {
        UploadManager::getInstance()->reserveSlot(getUser(), 3600);
    }
}
void UserInfoBase::grantSlotDay()
{
    if(getUser())
    {
        UploadManager::getInstance()->reserveSlot(getUser(), 24*3600);
    }
}
void UserInfoBase::grantSlotWeek()
{
    if(getUser())
    {
        UploadManager::getInstance()->reserveSlot(getUser(), 7*24*3600);
    }
}
void UserInfoBase::ungrantSlot()
{
    if(getUser())
    {
        UploadManager::getInstance()->unreserveSlot(getUser());
    }
}
*/
// !SMT!-UI
void UserInfoBase::grantSlotPeriod(const string& hubHint, void *period)
{
	if (period && getUser())
		UploadManager::getInstance()->reserveSlot(HintedUser(getUser(), hubHint), (uint64_t)period);
}
void UserInfoBase::connectFav()
{
	if (getUser())
	{
		string url = FavoriteManager::getInstance()->getUserURL(getUser());
		if (!url.empty())
		{
			HubFrame::openWindow(Text::toT(url));
		}
	}
}
void UserInfoBase::grantHour(const string& hubHint)
{
	if (getUser())
	{
		UploadManager::getInstance()->reserveSlot(HintedUser(getUser(), hubHint), 3600);
	}
}
void UserInfoBase::grantDay(const string& hubHint)
{
	if (getUser())
	{
		UploadManager::getInstance()->reserveSlot(HintedUser(getUser(), hubHint), 24 * 3600);
	}
}
void UserInfoBase::grantWeek(const string& hubHint)
{
	if (getUser())
	{
		UploadManager::getInstance()->reserveSlot(HintedUser(getUser(), hubHint), 7 * 24 * 3600);
	}
}
void UserInfoBase::ungrant()
{
	if (getUser())
	{
		UploadManager::getInstance()->unreserveSlot(getUser());
	}
}

// !SMT!-S
void UserInfoBase::pm_msg(void *param)
{
	const tstring *pmessage = (const tstring*)param;
	if (*pmessage != _T("\x01"))
		PrivateFrame::openWindow(HintedUser(getUser(), Util::emptyString), *pmessage, NULL);
}